package com.coderman.common.starter.logparam.service.logparams;

import com.alibaba.fastjson.JSON;
import com.coderman.common.starter.logparam.context.AopOnOffConfig;
import com.coderman.common.starter.logparam.enums.BasicTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created  on 2018-11-7.
 *
 * @author: fanchunshuai
 * @version: V1.0
 * @Desc:
 */
@Service
public class LogService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AopOnOffConfig aopOnOffConfig;

    /**
     * 打印出参
     *
     * @param returnValue
     */
    public void logOutputParam(Object returnValue, String key,String innerStr) {
        //获取总开关
        boolean logOutputParam = aopOnOffConfig.getLogoutputrefer();
        if (returnValue != null && StringUtils.isNotBlank(key)) {
            if (logOutputParam) {
                logger.info("key = {},{} outputParams = {}", key, innerStr, JSON.toJSONString(returnValue));
                return;
            }
            Set<String> basicTypeSet = BasicTypeEnum.getTypeSet();
            Class clazz = returnValue.getClass();
            if (returnValue instanceof List) {
                logger.info("key = {},{} outputParams.List = {}", key,innerStr, ((List) returnValue).size());
            } else if (returnValue instanceof Map) {
                logger.info("key = {},{} outputParams.Map = {}", key, innerStr, ((Map) returnValue).size());
            } else if (basicTypeSet.contains(clazz.getSimpleName())) {
                logger.info("key = {},{} outputParams.Basic = {}", key,innerStr, returnValue.toString());
            } else if (returnValue instanceof Set) {
                logger.info("key = {},{} outputParams.Set = {}", key, innerStr, ((Set) returnValue).size());
            }
            //数组类型判断比较多，暂时忽略
            else {
                logger.info("key = {},{} outputParams.Object = {}", key, innerStr, returnValue.toString());
            }
        }
    }


    /**
     * 打印内部服务的入参
     *
     * @param args
     * @param tmpKey
     */
    public void logInputParam(final Object[] args, final String tmpKey) {
        //记录入参
        StringBuffer buffer = new StringBuffer("(");
        //获取总开关
        boolean logInputParamConfig = aopOnOffConfig.getLoginputrefer();
        if (args != null) {
            if (logInputParamConfig) {
                //warning JSON could be large........
                logger.info("key = {},inner inputParams = {}", tmpKey, JSON.toJSONString(args));
                return;
            }
            Set<String> basicTypeSet = BasicTypeEnum.getTypeSet();

            for (Object object : args) {
                if (object != null) {
                    Class clazz = object.getClass();
                    if (object instanceof List) {
                        buffer.append("List:" + ((List) object).size() + ",");
                    } else if (object instanceof Map) {
                        buffer.append("Map:" + ((Map) object).size() + ",");
                    } else if (basicTypeSet.contains(clazz.getSimpleName())) {
                        buffer.append(object.toString() + ",");
                    } else if (object instanceof Set) {
                        buffer.append("Set:" + ((Set) object).size() + ",");
                    } else {
                        buffer.append(object.toString() + ",");
                    }
                } else {
                    buffer.append("null,");
                }
            }
            String resultLog = buffer.toString();
            if (resultLog.endsWith(",")) {
                resultLog = resultLog.substring(0, resultLog.length() - 2) + ")";
                logger.info("key = {},inner inputParams = {}", tmpKey, resultLog);
            }
        }
    }


    /**
     * 打印执行时间
     * @param tmpKey
     * @param exeTime
     */
    public void logExeTime(String tmpKey,long exeTime,String inner){
        logger.info("{} key = {},{} useTime = {}ms ",inner,tmpKey,inner, exeTime);
    }

}
